﻿#ifndef _HM_STORAGE_INTERFACE_H
#define _HM_STORAGE_INTERFACE_H
#include <stdint.h>
#include <time.h>
#include "storage_callback.h"
#include "media_frame_hd.h"
#define MAX_CH_NUM   16

#define FRAME_SOURCE_LOCAL    0
#define FRAME_SOURCE_SHAREMEM 1
#define FRAME_SOURCE_SIMULATE 2

typedef struct _CH_CFG_
{
	uint32_t isEnable;      //使能开关
	uint16_t real_ch;       //真实物理通道
	uint8_t  stream_type;   //主子码流
	uint8_t  src_type;      //视频源类型  0 内置视频缓冲 1跨进程共享内存 2模拟数据源
	uint32_t cache_sz;      //模块内置视频缓存大小
	uint32_t rec_disk_bit;  //录像磁盘编号 -1 所有磁盘都用 0x01 只录像在第一个盘上面

}CH_CFG_T;

typedef struct _StorageConfig_
{
    int32_t  channelNum;	    //支持的录像通道数
	int32_t  manualRecBIT;     //全时录像开关,接位处理

	uint8_t  bCycleRec;		 //循环录像
	uint8_t  bPrepare;		 //是否开启预录像
	uint8_t  bDisableCache;  // 是否禁用内置音视频缓存
	int32_t  nPerpareSecs;   //预录像最大5S，
	uint32_t sptClientNum;  //支持的客户数目
//  缓存使用信息
	//主码流，次码流 流媒体缓存
	uint32_t  main_media_cache;//内置流码流缓存
	//必须要的。
	uint32_t  buf_sz_flush;  //磁盘对齐刷新的大小
	uint32_t  buf_sz_replay; //回放的缓存
    uint32_t  buf_sz_frame;  //帧缓存大小
	char    record_path[200];
	char    record_file_ext[8]; //文件扩展名
	uint8_t   bLog;
	CH_CFG_T  ch_cfg[MAX_CH_NUM];//

}StorageConfig;

typedef struct _StorageSpaceInfo_
{
	uint32_t diskNum;          //磁盘个数
	uint32_t freeSpace;        //剩余空间
	uint32_t totalSpace;       //磁盘总大小
	uint32_t dataPercent;      //数据占用百分比s
}StorageSpaceInfo;

typedef enum _disk_bus_type_
{
	BUS_TYPE_SATA  = 0,		//本地磁盘
	BUS_TYPE_ESATA = 1,		//可以支持热插拨的SATA接口
	BUS_TYPE_USB   = 2,		//USB接口
	BUS_TYPE_MMC   = 3,      //MMC TF card
	BUS_TYPE_NAS   = 4,		//NAS
}DISK_BUS_TYPE;


typedef enum _playback_type_
{
	REPLAY_NULL = 0,					//未设置
	REPLAY_PAUSE,						//暂停
	REPLAY_STOP,						//停止

	REPLAY_NORMAL  = 0x10,				//正常回放
	REPLAY_ONEFRAME= 0x20,				//单帧播放
	REPLAY_SLOW    = 0x40,				//慢进 2, 4, 8, 16, 32
	REPLAY_FAST    = 0x80,				//快进 2, 4, 8, 16, 32
	REPLAY_REBACK  = 0x100,				//回退 8, 16, 32
}PLAYBACK_MODE;

typedef enum _FS_RECORD_TYPE_
{
	FS_RECORD_NONE			= 0x0000,		//没有录像
	FS_RECORD_SCHEDULE		= 0x0001,		//定时录像
	FS_RECORD_MANUAL		= 0x0002,		//手动录像
	FS_RECORD_MOTION		= 0x0004,	    //移动侦测报警录像
	FS_RECORD_IOALARM		= 0x0008,		//传感器报警录像
	FS_RECORD_SHELTER		= 0x0010,		//遮挡报警录像
	//后续扩展支持
	FS_RECORD_BEHAVIOR		= 0x0020,		//行为分析录像

}FS_REC_TYPE;

typedef struct _EXTRA_REC_INFO_
{
	time_t cur_tm;        //当时时间
	int   event_id;       //子事件ID
	char  extra_info[32]; //录像段标记TAG
}EXTRA_REC_INFO;

typedef enum _record_status_
{
	RECORD_STATUS_UNUSED = 0,		//未使用
	RECORD_STATUS_USED   = 0x01,	//正常使用中（未锁定、未隐藏）
	RECORD_STATUS_LOCK   = 0x02,	//被锁定
}REC_STATUS;

//==============================================
// Define data structure
//==============================================
typedef struct _DiskInfo_
{
	int32_t status;					//0 表示掉线　1 表示激活
	int32_t type;					//磁盘接口类型：本地 0 SATA）、1 E_SATA、2 USB， 3 IP_SAN、4 NAS、、等（只读�?
	int32_t property;				//属性：只读、冗余、读写
	int32_t isFormated;				//是否已经格式化
	int32_t diskIndex;				//磁盘编号
	int32_t portType;				//端口类型
	int32_t portNum;				//端口号
	uint32_t   recSpace;		//录像总容量：MB（只读）
	uint32_t   recFreeSpace;	//录像剩余容量：MB（只读）

	uint32_t   comPartSpace;    //通用盘的空间大小
	uint32_t   comPartFreeSpace;//剩余大小

	uint32_t   totalSpace;		//磁盘总容量MB
	char       diskName[20];     //设备名称
}DiskInfo;

typedef enum _FS_DATA_PART_TYPE_
{
	FS_PART_COMMON = 0,  //通用普通磁盘
	FS_PART_RECORD = 1,  //录像区 预分配区
	FS_PART_PIC    = 2,  //图片区 预分配区
	FS_PART_LOG    ,    //日志区

}FS_DATA_PART_TYPE;

typedef struct _FS_PART_INFO_
{
	uint8_t       data_type;   // FS_DATA_PART_TYPE
	uint8_t       is_use_percent; //使用百分比
	union
	{
		uint32_t  disk_percent; //磁盘分区百分比
		uint32_t  part_sz_MB;   //分区大小 单位MB
	};
	uint32_t      blk_MB;        //邓分配文件块大小 单位MB
	uint32_t      index_blk_sz; //录像区和图片区生效，索引段大小最小2K，缺省值4K
}FS_PART_INFO;

typedef struct _PART_TABLE_
{
	int         num; //分区总数
	FS_PART_INFO * part;
}FS_PART_TABLE;

struct UDevInfo
{
	char mountPoint[64];	//挂载路径
	char deviceText[36];	//设备名称
	uint64_t totalSize;	//Byte
	uint64_t freeSpace;	//Byte
	int32_t udevStatus;			//0-正常挂载,可读写;1-正常挂载,不可读写;2-正常挂载,未格式化;3-正常卸载
};
typedef struct _RECORD_CH_INFO_
{
	uint32_t chManualBIT;
	int32_t  sptChNum;  //支持的通道数
	char   recType[32];//最多支持32通道
}RECORD_CH_INFO;


typedef struct _BACKUP_PARAM_
{
	int32_t     selectMode;			//选择备份模式
	uint16_t	style;				//采用USB, FTP, DISK, DVD, 方式备份
	uint16_t 	fileFormat;			//备份格式, [0 *.asf], [1 *.mp4] [2  bin]
	int32_t     recStartOffset;		//开始的偏移
	int32_t     recNum;				//备份的数目
	char		partPath[128];		//挂载相对路径
}BACKUP_PARAM;

typedef struct _PLAYBACK_INFO_
{
	uint16_t	synchro;		//同步 0, 异步 1
	uint16_t	chnn;			//通道
	uint16_t	status;			//状态PLAYBACK_TYPE
	uint16_t	speed;			//速率 1, 2, 4, 8, 16, 32
	int64_t		time;			//帧时间
	int32_t	    playClientNum;  //
}PLAYBACK_INFO;

typedef enum _DEV_STATUS
{
	DEV_NORMARL       = 0,
	DEV_NOREADWRITE   = 1,
	DEV_UNFORMATED    = 2,
	DEV_UNLOADED      = 3,
}DEV_STATUS;

typedef struct _SCHEDULE_REC_
{
    int32_t is_Enable;
	uint64_t scheduleTime[7];
}SCHDULE_REC;

typedef struct _DISK_FBLK_INFO_
{
	char dev[128];  //设备名
	int  part_no;   //分区编号
	uint32_t  block_idx; //块索引编号
	uint32_t  block_sz;  //块大小
	uint32_t  free_sz;   //剩余大小
}DISK_FBLK_INFO;

//录像段文件信息
typedef struct _FILE_INFO_
{
	uint32_t    NO;				//文件临时编号
	uint8_t		bCheck;			//是否选中
	uint8_t		channel;		//通道号
	uint8_t		dataSource;		//数据来源	DATA_SOURCE_ID
	uint8_t     timeZone;       //时区
	int64_t	    fileSize;		//录像段大小

	uint32_t    tmStart;		//开始时间 16+
	uint32_t	tmEnd;			//结束时间

	uint32_t	indexNO;		//磁盘上面的索引
	uint8_t		status;			//状态：REC_STATUS
	uint8_t		diskIndex;		//磁盘编号
	uint8_t     recSegIndex;	//录像段编号
	uint8_t     resever;        //保留
	uint16_t	recordType;	   //主录像类型 record_type_
	uint16_t    eventType;     //子录像类型
}FILE_INFO;

typedef struct _REC_DAY_
{
	time_t tm_day_start;  // 日期的开始
	time_t tm_day_end;	  // 日期的结束　
}FS_REC_DAY;	//便于快速查看所有录像段

typedef enum _download_type
{
	DOWNLOAD_PLAY   = 0,	//远程回放
	DOWNLOAD_BACKUP = 1,	//远程备份
}DOWNLOAD_TYPE;

typedef struct _DOWNLOAD_RECORD_
{
	int32_t	     downloadType;		//DOWNLOAD_TYPE // 0: 远程回放 1:远程备份
	time_t	     startTime;			//起始时间 实时备份
	time_t	     endTime;			//结束时间(在downloadType为DOWNLOAD_PLAY时无效）
	int32_t      ch;                //通道
	int32_t		 recType;			//录像类型
	int32_t		 userBIT;			//用户ID位
}DOWNLOAD_RECORD;

typedef struct _DISK_PERFORMANCE_
{
	int32_t wtSpeed;	//KB/S 会精确到后面两位小数点．
	int32_t rdSpeed;	//KB/S
	int32_t realWtSpd;  //KB/S 实时的写入速度
	int32_t realRdSpd;	//KB/S 实时的读取速度
}DiskPerformance;

typedef struct _REC_SEGMENT_
{
	uint8_t		reserve;		//保留
	uint8_t		channel;		//通道号
	uint8_t		dataSource;		//数据来源	DATA_SOURCE_ID
	uint8_t     timeZone;       //时区2017年5月27日       //uint8_t     reserve;        、、
	int64_t	    fileSize;		//录像段大小

	uint32_t	tmStart;		//开始时间 16+
	uint32_t	tmEnd;			//结束时间

	uint32_t	indexNO;		//磁盘上面的索引
	uint8_t		status;			//状态：RECORD_FILE_STATUS
	uint8_t		diskIndex;		//磁盘编号
	uint8_t     recSegIndex;	//录像段编号
	uint8_t		reserve2;		//保留2

	uint32_t	recordType;		//录像类型 record_type_
	uint32_t	type_ex;		//扩展类型
}RECORD_SEGMENT,*PRECORD_SEGMENT;

const int segment_len = sizeof(RECORD_SEGMENT);

typedef struct _REC_FINFO_
{
	char    frec_path[200];
	int64_t file_sz;
}REC_FINFO, * PREC_FINFO;

#define  LOCAL_CLIENT_ID      0
#define  TELNET_CLINET_ID     1   //网络用户从1开始编号，可以支持到4个
#define  ALL_REC_TYPE         -1

typedef int (*HM_GetFrame)(unsigned char * buf,uint32_t dataSize,int ch);

#ifdef __cplusplus
extern "C" {
#endif

	//录像模块初始化接口
	int   HM_Storage_Init(StorageConfig cfg);

	int   HM_Storage_UnInit();
	//获取录像最大时间
	time_t  HM_GetRecMaxTime();

	//磁盘管理接口
	//判断当前磁盘是否已经初始化
	int  HM_disk_is_init(const char * dev);

	int  HM_SetPartition(const char * dev, FS_PART_TABLE * part_table);

	int  HM_FormatDisk(const char * dev);

	int  HM_FormatToRecdisk(const char * dev, int blockMB, int compartMB, int useSpaceMB);

	StorageSpaceInfo  HM_GetDiskSpaceInfo();

	int  HM_GetDiskInfo(char  * buf, int bufSize);

	//设置获取音视频数据回调函数,存储模块内置缓存就可以取消了
	void  HM_SET_GetFrame_CBK(HM_GetFrame cbak_funcGetFrame);

	void  HM_SET_STATUS_CBAK(STORAGE_STATUS_CBAK cbak);

	int HM_Snap(int ch);
	//录像功能是否正常
	int  HM_RecordStart(int ch);

	int  HM_RecorcStop(int ch);

	int  HM_RecordIsOk();

	//按通道号只停止手动录像
	int  HM_ManualRecStop(int ch);

	//按通道位标记一次做到停止
	int  HM_SET_RECORD_SWITCH(int chSwith);

	//设置是否循环录像
	int  HM_CycleRec(int bEnable);

	//设置录像计划表
	int  HM_ScheduleTimeGet(int ch, SCHDULE_REC schduleTime);

	//获取某个通道的计划表
	SCHDULE_REC  HM_ScheduleTimeSet(int ch);

	int HM_PicSearch(char* fileBuf, int bufSize, time_t tmStart, time_t tmEnd, int32_t chMask);

	//内置缓冲,视频及录像缓冲使用
	int  HM_FifoWriteFrame(unsigned char * buf,uint32_t dataSize,int frameType,int ch);
	int  HM_FifoClearData(int ch);

	int  HM_FifoReadFrame(unsigned char * buf,uint32_t dataSize,int ch,int clientID);
	int  HM_FifoSeekTime(int64_t startTime, int prepareSecs,int ch, int clientID);
	int  HM_FifoGetFrameWater(int ch,int clientID);

	int  HM_FifoConsumeFrame(int frmSize,int ch,int clientID);

	//环形缓冲信息
	int  HM_FifoGetDataSize(int ch);

	int  HM_FIFOGetWarter(int ch);

	int  HM_GetRecordPercent(int ch);

	int  HM_GetRecordIndex(int ch);

	int  HM_GetRecordSn(int ch);
	//回放使用
	//拷贝一帧数据出来

	int  HM_ReplayFifoReadFrame(unsigned char * buf,int bufSize,int ch,int clientID);

	int  HM_ReplayFifoClear(int ch,int clientID);

	int  HM_ReplaySyncWait( uint64_t frmTm,int mulCH_sync,int ch,int clientID);

	RECORD_CH_INFO  HM_GetRecordChInfo();

	void HM_SetRecordCycle(uint8_t bEnable);

	int  HM_SetPreareRec(uint8_t bEnable, int nSecs);

	//搜索当月中存在录像的天数
	int  HM_SearchRecordAllDay(char* recDayBuf,int bufSize,int64_t chBit);

	int  HM_SearchRecordDayOfMonth(int year, int month, int recType);

    int  HM_SearchHistoryRec(unsigned char* fileBuf,int bufSize,time_t tmStart,time_t tmEnd,int32_t ch,int recType,int clientID);

    int  HM_SearchRec( char* fileBuf,int bufSize,time_t tmStart, time_t tmEnd, int32_t chMask,int recType,int storType,int clientID);

	int  HM_SearchRecfile(time_t tmStart, time_t tmEnd, int32_t chMask);

	int  HM_DelOldRecord(time_t oldTime);

	//录像段读取接口
	int  HM_PlaybackBytime(time_t startTime,time_t endTime,  int channel,int clientID) ;

	int  HM_PlaybackByFile(const char* file, time_t startTime);

	int  HM_PlaybackStop(int ch,int clientID) ;

	int  HM_PlaybackStatus(int ch,time_t playTime,int clientID);

	int  HM_PlaybackSeekTime(time_t time,int ch,int clientID) ;

	int  HM_PlaybackSetMode(int playMod, int speed,int ch,int clientID);
   
	int  HM_PlaybackGetTime(int ch, int clientID);

	//回放接口,可以支持远程点播,ClientID  0:表示本地用户　　1：远程用户　

	StorageConfig  HM_GetStorageCfg();

	int  HM_GetDataPercent();

#ifdef __cplusplus
}
#endif
#endif /* _STORAGE_INTERFACE_H */
